package com.msg.xml;

import java.util.ArrayList;
import java.util.List;

/**
 * This class read in the available seats data from XML and save it in the capacity records list
 * @author jeson9603
 *
 */
public class AvaSeats_Manipulator extends Table_Manipulator {

	private List<CapacityRecord> records;
	private List<List<String>> avaSeatsData = new ArrayList<List<String>>();
	private List<String> killedData = new ArrayList<String>();
	
	
	public AvaSeats_Manipulator(Property prop) {
		super(prop);
	}
	/**
	 * get the event code, ticket type and available seats data from XML file within the Capacity field
	 * @return
	 */
	@Override
	protected String getSpecificData() {
		//pinpoint the tag *** CAPACITY first
		XMLhandler.findNodeByTag("***       AVAILABLE SEATS");
		//move the cursor forward by three positions
		XMLhandler.moveCursorForward();
		XMLhandler.moveCursorForward();
		XMLhandler.moveCursorForward();
		while(true) {
			List<String> contents = XMLhandler.getDataList();
			//reach the end, terminate the iteration
			if(contents.get(0).compareTo("TOTAL") == 0)
				break;
			//jump over the blank line
			if(contents.get(0).compareTo("") == 0)
				continue;
			if(contents.get(1).compareTo("KILL") == 0) {
				String eventCode = contents.get(0);
				killedData.add(eventCode);
				killedData.add(TableUtility.getTicketType(eventCode));
				for(int i = 4; i < contents.size(); i++) {
					if(contents.get(i).compareTo("") == 0)
						break;
					killedData.add(contents.get(i));
				}
				updateKill();
			}
			//only read the rows that event codes end with (TOTAL)
			else if(contents.get(0).endsWith("(TOTAL)")) {
				List<String> dataRow = new ArrayList<String>();
				String eventCode = contents.get(0);
				eventCode = eventCode.substring(0, eventCode.indexOf(" (TOTAL)")-1);
				dataRow.add(eventCode);
				dataRow.add(TableUtility.getTicketType(eventCode));
				for(int i = 4; i < contents.size(); i++) {
					if(contents.get(i).compareTo("") == 0)
						break;
					dataRow.add(contents.get(i));
				}
				avaSeatsData.add(dataRow);
			}
		}
		return null;
	}

	/**
	 * find a capacity record in the given list of capacity records
	 * @param eventCode
	 * @param ticketType
	 * @param ticketLv
	 * @return, the capacity record if all parameters match, or return null
	 */
	private CapacityRecord findRecord(String eventCode, String ticketType, char ticketLv) {
		for(int i = 0; i < records.size(); i++) {
			CapacityRecord record = records.get(i);
			if(record.getEventCode().compareTo(eventCode) != 0)
				i += prop.getTICKETLEVEL_NUM() - 1;
			else if((record.getTicketType().compareTo(ticketType) == 0) && (record.getTicketLevel() == ticketLv)) 
				return record;
		}
		return null;
	}
	
	/**
	 * update the tickets' kill information in the capacity summary table
	 */
	private void updateCapacitySummary() {
		String eventId = TableUtility.getEventId(killedData.get(0));
		for(int i = 2; i < killedData.size(); i++) {
			String ticketLvId = TableUtility.getTicketLvID("" + (char)('A' + i - 2));
			DBRequest request = new DBRequest();
			request.resultCol.add("Kills");
			request.entries.add("Event_Id");
			request.entries.add("Ticket_Level_id");
			request.data.add(eventId);
			request.data.add(ticketLvId);
			
			//update the capacity summary table
			if(DBhandler.hasData("capacity_summary", request)) {
				request.resultColData.add(killedData.get(i));
				DBhandler.updateData("capacity_summary", request);
			}
			
			//insert the data into capacity summary table
			else {
				DBRequest insertionRequest = new DBRequest();
				insertionRequest.entries.add("Event_Id");
				insertionRequest.entries.add("Ticket_Level_id");
				insertionRequest.entries.add("Kills");
				insertionRequest.data.add(eventId);
				insertionRequest.data.add(ticketLvId);
				insertionRequest.data.add(killedData.get(i));
				DBhandler.insertData("capacity_summary", insertionRequest);
			}
		}
	}
	
	/**
	 * updating the tickets' kill information into the capacity table
	 */
	private void updateCapacity() {
		String eventId = TableUtility.getEventId(killedData.get(0));
		String ticketTypeId = TableUtility.getTicketTypeId(killedData.get(1));
		for(int i = 2; i < killedData.size(); i++) {
			String ticketLvId = TableUtility.getTicketLvID("" + (char)('A' + i - 2));
			
			//first update the Kills information in capacity_summary table
			DBRequest request = new DBRequest();
			request.resultCol.add("Event_Id");
			request.entries.add("Event_Id");
			request.entries.add("Ticket_Type_Id");
			request.entries.add("Ticket_Level_Id");
			request.data.add(eventId);
			request.data.add(ticketTypeId);
			request.data.add(ticketLvId);
			if(!DBhandler.hasData("capacity", request)) {
				request.resultCol.remove("Event_Id");
				request.entries.add("Kills");
				request.data.add(killedData.get(i));
				DBhandler.insertData("capacity", request);
			}
			else {
				request.resultCol.remove("Event_Id");
				request.resultCol.add("Kills");
				request.resultColData.add(killedData.get(i));
				DBhandler.updateData("capacity", request);
			}
		}
	}
	
	
	/**
	 * updating the killed seats information into the capacity table and the capacity_summary table
	 */
	public void updateKill() {
		updateCapacitySummary();
		updateCapacity();
	}
	/**
	 * transform the raw data of available seats read from XML to the CapacityRecords
	 * @return 
	 */
	@Override
	protected String update() {
		for(int i = 0; i < avaSeatsData.size(); i++) {
			List<String> rowData = avaSeatsData.get(i);
			for(int j = 0; j < prop.getTICKETLEVEL_NUM(); j++) {
				CapacityRecord record = findRecord(rowData.get(0), rowData.get(1), (char)('A' + j));
				//only the record already exist will be used, its available seats column will be set.
				if(record != null) {
					record.setAvaSeats(rowData.get(2 + j));
				}
			}
		}
		return null;
	}

	/**
	 * give an capacity records list with capacity data already exist
	 * @param o, a list of capacity records
	 */
	@Override
	@SuppressWarnings("unchecked")
	protected void pushData(Object o) {
		records = (List<CapacityRecord>)o;
	}
}
